package com.threeti.mecool.core.domain.model.plan.pojo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonManagedReference;

public class UserJob {
	private Long id;
	private Integer version;
	private Long userId;
	private Job job;
	private int finished;
	private List<UserStep> userSteps = new ArrayList<UserStep>(0);
	private transient Long jobId;

	public Step getNextStep() {
		Step step = job.getFirstStep();
		if (userSteps.size() != 0) {
			UserStep userStep = findUserStepByStepId(step.getId());
			while (userStep != null && userStep.isFinished()) {
				step = userStep.getNextStep();
				if (step == null) {
					break;
				}
				userStep = findUserStepByStepId(step.getId());
			}
		}
		return step;
	}
	
	public UserStep findUserStepByStepId(Long stepId) {
		if (stepId == null) {
			return null;
		}
		for (UserStep userStep : userSteps) {
			if (stepId.equals(userStep.getStepId())) {
				return userStep;
			}
		}
		return null;
	}
	
	public UserStep findUserStepByStep(Step step) {
		if (step == null) {
			return null;
		}
		for (UserStep userStep : userSteps) {
			if (step.getId().equals(userStep.getStepId())) {
				return userStep;
			}
		}
		UserStep userStep = newUserStep(step);
		return userStep;
	}
	
	private UserStep newUserStep(Step step) {
		UserStep userStep = new UserStep();
		UserTask userTask = new UserTask();
		userTask.setTask(step.getTask());
		
		if (step instanceof RouteStep) {
			userStep = new UserRouteStep();
		} else if (step instanceof GroupStep) {
			userStep = new UserGroupStep();
		} else {
			userStep = new UserStep();
		}
		userStep.setStep(step);
		userStep.setUserTask(userTask);
		userSteps.add(userStep);
		userStep.setUserJob(this);
		return userStep;
	}
	
	public UserStep getNextUserStep() {
		UserStep userStep = null;
		Step step = getNextStep();
		
		/* test begin */
		step = job.getFirstStep();
		if (step != null) {
			do {
				if (step == null) {
					userStep = null;
					break;
				}
				userStep = findUserStepByStepId(step.getId());
				if (userStep == null) {
					userStep = newUserStep(step);
				}
				step = userStep.getNextStep();
			} while (userStep.isFinished());
		}
		
		/* test end */
		
//		if (step != null) {
//			userStep = findUserStepByStepId(step.getId());
//			if (userStep == null) {
//				UserTask userTask = new UserTask();
//				userTask.setTask(step.getTask());
//				
//				if (step instanceof RouteStep) {
//					userStep = new UserRouteStep();
//				} else if (step instanceof GroupStep) {
//					userStep = new UserGroupStep();
//				} else {
//					userStep = new UserStep();
//				}
//				userStep.setStep(step);
//				userStep.setUserTask(userTask);
//				userSteps.add(userStep);
//				userStep.setUserJob(this);
//			}
//		}
		return userStep;
	}

	/**
	 * @return unmodifiableList
	 */
	@JsonManagedReference
	public List<UserStep> getUserSteps() {
		return Collections.unmodifiableList(userSteps);
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public Long getUserId() {
		return userId;
	}

	public void setUserId(Long userId) {
		this.userId = userId;
	}

	@JsonIgnore
	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}

	public int getFinished() {
		return finished;
	}

	public void setFinished(int finished) {
		this.finished = finished;
	}

	public void setUserSteps(List<UserStep> userSteps) {
		this.userSteps = userSteps;
	}

	public Long getJobId() {
		if (jobId == null && job != null) {
			jobId = job.getId();
		}
		return jobId;
	}

	public void setJobId(Long jobId) {
		this.jobId = jobId;
	}

}
